﻿using System;
using System.Collections.Generic;
using Bridge.Workflow.Domain;
using Bridge.Workflow.Domain.Workflows;
using Microsoft.EntityFrameworkCore;
using Volo.Abp;
using Volo.Abp.EntityFrameworkCore.Modeling;

namespace Bridge.Workflow.EntityFrameworkCore
{
    public static class WorkflowDbContextModelCreatingExtensions
    {
        public static void ConfigureWorkflow(
            this ModelBuilder builder,
            Action<WorkflowModelBuilderConfigurationOptions> optionsAction = null)
        {
            Check.NotNull(builder, nameof(builder));

            //var options = new WorkflowModelBuilderConfigurationOptions(
            //    WorkflowDbProperties.DbTablePrefix,
            //    WorkflowDbProperties.DbSchema
            //);

            //optionsAction?.Invoke(options);
            builder.Entity<PersistedWorkflowDefinition>(s =>
            {
                s.ToTable("workflowdefinitions");
                s.ConfigureByConvention();
                s.Property(u => u.Version).HasDefaultValue(1);
                s.HasKey(u => new { u.Id, u.Version });
                s.Property(u => u.Id).HasMaxLength(36);
                s.Property(u => u.Title).HasMaxLength(256);
                s.Property(u => u.Group).HasMaxLength(100);
                s.Property(u => u.Icon).HasMaxLength(50);
                s.Property(u => u.Color).HasMaxLength(50);
                s.Property(u => u.Id).HasMaxLength(36);
                s.Property(u => u.Inputs).HasConversion(u => u.ToJsonString(false, false), u => u.FromJsonString<IEnumerable<IEnumerable<IEnumerable<WorkflowFormData>>>>());
                s.Property(u => u.Nodes).HasConversion(u => u.ToJsonString(false, false), u => u.FromJsonString<IEnumerable<WorkflowNode>>());
                //s.Property(u => u.IsDeleted).HasDefaultValue(0);
                s.Property(u => u.CreationTime);
                s.Property(u => u.CreatorId);
                s.Property(u => u.LastModificationTime);
                s.Property(u => u.LastModifierId);
                //s.Property(u => u.DeletionTime);
                //s.Property(u => u.DeleterId);
                s.Property(u => u.Description);
            });

            builder.Entity<PersistedEvent>(s =>
            {
                s.ToTable("WorkflowEvents");
                s.ConfigureByConvention();
                s.HasKey(u => new { u.Id });
                s.Property(u => u.EventName).HasMaxLength(256);
                s.Property(u => u.EventKey).HasMaxLength(256);
                s.Property(u => u.EventData);
                s.Property(u => u.EventTime);
                s.Property(u => u.IsProcessed);
                s.Property(u => u.TenantId);
                s.Property(u => u.CreationTime);
                s.Property(u => u.CreatorId);
            });

            builder.Entity<PersistedWorkflow>(s =>
            {
                s.ToTable("Workflows");
                s.ConfigureByConvention();
                s.HasKey(u => new { u.Id });
                s.Property(u => u.Id).HasMaxLength(36);
                s.Property(u => u.WorkflowDefinitionId).HasMaxLength(36);
                s.Property(u => u.Version);
                s.Property(u => u.Description);
                s.Property(u => u.Reference).HasMaxLength(256);
                s.Property(u => u.NextExecution);
                s.Property(u => u.Data);
                s.Property(u => u.CompleteTime);
                s.Property(u => u.Status);
                s.Property(u => u.CreateUserIdentityName).HasMaxLength(256);
                s.Property(u => u.TenantId);
                //s.Property(u => u.IsDeleted).HasDefaultValue(0);
                s.Property(u => u.CreationTime);
                s.Property(u => u.CreatorId);
                s.Property(u => u.LastModificationTime);
                s.Property(u => u.LastModifierId);
                //s.Property(u => u.DeletionTime);
                // s.Property(u => u.DeleterId);
                s.Property(u => u.Description);
            });

            builder.Entity<PersistedWorkflow>().HasOne(u => u.WorkflowDefinition).WithMany().HasForeignKey(u => new { u.WorkflowDefinitionId, u.Version });
            //return builder;

            /* Configure all entities here. Example:

            builder.Entity<Question>(b =>
            {
                //Configure table & schema name
                b.ToTable(options.TablePrefix + "Questions", options.Schema);
            
                b.ConfigureByConvention();
            
                //Properties
                b.Property(q => q.Title).IsRequired().HasMaxLength(QuestionConsts.MaxTitleLength);
                
                //Relations
                b.HasMany(question => question.Tags).WithOne().HasForeignKey(qt => qt.QuestionId);

                //Indexes
                b.HasIndex(q => q.CreationTime);
            });
            */
        }

        public static ModelBuilder ConfigWorkflowCore(this ModelBuilder modelBuilder)
        {
            var builder = modelBuilder.Entity<PersistedWorkflowDefinition>();
            builder.Property(u => u.Version).HasDefaultValue(1);
            builder.HasKey(u => new { u.Id, u.Version });
            builder.Property(u => u.Title).HasMaxLength(256);
            builder.Property(u => u.Group).HasMaxLength(100);
            builder.Property(u => u.Icon).HasMaxLength(50);
            builder.Property(u => u.Color).HasMaxLength(50);
            builder.Property(u => u.Id).HasMaxLength(100);
            builder.Property(u => u.Inputs).HasConversion(u => u.ToJsonString(false, false), u => u.FromJsonString<IEnumerable<IEnumerable<IEnumerable<WorkflowFormData>>>>());
            builder.Property(u => u.Nodes).HasConversion(u => u.ToJsonString(false, false), u => u.FromJsonString<IEnumerable<WorkflowNode>>());

            modelBuilder.Entity<PersistedWorkflow>().HasOne(u => u.WorkflowDefinition).WithMany().HasForeignKey(u => new { u.WorkflowDefinitionId, u.Version });
            return modelBuilder;
        }
    }
}